package com.pug.logs.aop;

import com.ksd.pug.commons.ex.PugBussinessException;
import com.ksd.pug.commons.ex.PugValidationException;
import com.ksd.pug.commons.utils.ip.IpUtils;
import com.ksd.pug.commons.utils.req.ServletUtils;
import com.pug.logs.config.AspectProperties;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;

/**
 * @author 飞哥
 * @Title: 学相伴出品
 * @Description: 飞哥B站地址：https://space.bilibili.com/490711252
 * 记得关注和三连哦！
 * @Description: 我们有一个学习网站：https://www.kuangstudy.com
 * @date 2021/12/21 23:31
 */
@Aspect // 代表是一个aop切面
@Slf4j
@Order(2)
public class PugLogAspect {

    public PugLogAspect() {

    }

    private AspectProperties aspectProperties;

    public PugLogAspect(AspectProperties aspectProperties) {
        this.aspectProperties = aspectProperties;
    }

    // 1: 定义切点，切点标注有注解@KsdLog的的所有函数，通过 @Pointcut 判断才可以进入到具体增强的通知
    @Pointcut("@annotation(com.ksd.pug.commons.anno.PugLog)")
    public void logpointcut() {
    }

    // 2: 通知 （切点或者切点表达式）
    @Around("logpointcut()")
    public Object doAfterReturning(ProceedingJoinPoint proceedingJoinPoint) {
        // 1:方法执行的开始时间
        long starttime = System.currentTimeMillis();
        // 2:执行真实方法
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        System.out.println(signature.getMethod().getName());
        System.out.println(signature.getReturnType());
        System.out.println(signature.getParameterNames());
        System.out.println(signature.getParameterTypes());
        // 核心代码，这个前后通知分界线
        log.info("1-----around before logs------>日志进来了");
        Object methodReturnValue = null;
        try {

            methodReturnValue = proceedingJoinPoint.proceed();

            // 3:方法执行的结束时间
            long endtime = System.currentTimeMillis();
            // 4：方法的总耗时
            long total = endtime - starttime;
            log.info("2-----around after logs------>日志进来了=====当前方法:{}，执行的时间是：{} ms", signature.getMethod().getName(), total);
            return methodReturnValue;
        } catch (PugBussinessException ex) {
            throw ex;
        } catch (PugValidationException ex) {
            throw ex;
        } catch (Throwable ex) {
            throw new RuntimeException("服务器限流异常，请稍候再试");
        }
    }

    protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult) {
        try {
            // *========数据库日志=========*//
            // 请求的地址
            String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
            // 设置方法名称
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();

        } catch (Exception exp) {
            // 记录本地异常日志
            log.error("==前置通知异常==");
            log.error("异常信息:{}", exp.getMessage());
            exp.printStackTrace();
        }
    }
}
